package interview.i_003_concurrent;

import org.junit.jupiter.api.Test;

/**
 * 死锁 Demo
 * jps 命令定位进程号，jstack 找到死锁查看
 * <p>
 * jps -l
 * 11968 interview.i_001_concurrent.T001_DeadLock
 * 6100 sun.tools.jps.Jps
 * jstack 11968
 * Found one Java-level deadlock
 * Java stack information for the threads listed above
 * Found 1 deadlock
 */
class T001_DeadLock {
    final Object resourceA = new Object();
    final Object resourceB = new Object();

    @Test
    void deadLock1() {
        new Thread(() -> {
            synchronized (resourceA) {
                System.out.printf("%s 自己持有 %s，尝试持有 %s%n", Thread.currentThread().getName(), resourceA, resourceB);
                try {
                    Thread.sleep(1);
                } catch (InterruptedException ignored) {
                }
                synchronized (resourceB) {
                }
            }
        }).start();
        new Thread(() -> {
            synchronized (resourceB) {
                System.out.printf("%s 自己持有 %s，尝试持有 %s%n", Thread.currentThread().getName(), resourceA, resourceB);
                try {
                    Thread.sleep(1);
                } catch (InterruptedException ignored) {
                }
                synchronized (resourceA) {
                }
            }
        }).start();
    }

    @Test
    void deadLock2() {
        Thread thread = new Thread(() -> {
            synchronized (resourceA) {
            }
        });
        new Thread(() -> {
            synchronized (resourceA) {
                thread.start();
                try {
                    thread.join(); // 调用的 wait，会释放锁
                } catch (InterruptedException ignored) {
                }
            }
        }).start();
    }
}